package com.caipiao.aspect;



import com.caipiao.util.JsonUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;


@Component
@Aspect
public class AdviceController
{
    private static final Logger LOGGER = LoggerFactory.getLogger(AdviceController.class);

    @Around("execution(* com.*.controller..*(..))")
    public Object process(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        LOGGER.info("目标方法为：" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName() + "用户请求的ip地址为" + getIpAddr(request));
        Object[] args = point.getArgs();
        LOGGER.info("参数为：" + Arrays.toString(args));
        Object returnValue = point.proceed(args);
        LOGGER.info("返回值为：" + JsonUtils.objectToJson(returnValue));
        return returnValue;
    }

    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    @AfterThrowing(value="execution(* com.*.*..*(..))", throwing="e")
    public void afterThrowing(JoinPoint joinPoint, Exception e){
        String methodName = joinPoint.getSignature().getName();
        LOGGER.error("异常方法:" + methodName + " 异常原因:" + e);
        StringWriter sw=new StringWriter();
        e.printStackTrace(new PrintWriter(sw,true));
        LOGGER.error("异常详细信息:"+sw.toString());
    }
}
